package com.specter.sure.core.filter;

import java.io.IOException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.specter.sure.core.AuthConfig;
import com.specter.sure.core.AuthConsts;
import com.specter.sure.core.AuthContext;
import com.specter.sure.core.AuthorizedProvider;
import com.specter.sure.core.PermissionProvider;
import com.specter.utils.URLUtils;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

/**
 * Note:系统权限过滤器
 * 
 * @author Liang.Wang
 * @version 2020-02-05
 */
@Slf4j
@Component
public class SpecterSecurityFilter implements Filter {

	private @Autowired AuthConfig PROP;
	private @Autowired AuthorizedProvider authorized;
	private @Autowired PermissionProvider permission;


	@Override
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;

		String path = URLUtils.getRequestURL(request, PROP.PRIVILEGE_PARAMETERS);
		try {
			AuthContext.init(request, response);

			boolean isAuthorize = true, isPrivilege = true;
			switch (AuthConsts.Level.valueOf(PROP.PRIVILEGE_LEVEL)) {
				case NONE: // 不做任何检查
					log.info("无安全控制，请勿正式环境使用！！！");
					break;
				case LOW: // 只检查是否登录
					isAuthorize = authorized.isNoControlResource(path) || authorized.validate();
					break;
				case MIDDLE: // 默认：登录且过滤已标记资源
					isAuthorize = authorized.isNoControlResource(path) || authorized.validate();
					isPrivilege = isAuthorize && (!permission.isControlResource(path) || permission.privilege(path));
					break;
				case HIGH:// 登录且只允许已标记资源
					isAuthorize = authorized.isNoControlResource(path) || authorized.validate();
					isPrivilege = isAuthorize && (permission.isNoControlResource(path) || permission.privilege(path));
					break;
				default:
					throw new ServletException("安全级别配置错误( NONE, LOW, MIDDLE, HIGH )");
			}

			log.debug("$$$ Request: {}:{} ==> Results: isAuthorize:{}, isPrivilege:{}", request.getRemoteAddr(), path, isAuthorize, isAuthorize);
			if (isAuthorize && isPrivilege) {
				chain.doFilter(req, res);// 验证通过继续
			} else {
				request.setAttribute("isAuthorize", isAuthorize);
				request.getRequestDispatcher(AuthConsts.URL_NAUTH_FAILURE).forward(request, response);// 跳转到Controller中处理
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		} finally {
			AuthContext.remove();
		}
	}
}